<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>实例操作</title>
    <style>
        *{
            padding: 0;
            margin: 0;
            box-sizing: content-box;
        }
        body{
            padding: 30px;
        }
        .slide{
            width: 300px;
            display: flex;
            flex-direction: column;
        }
        .slide dt{
            height: 30px;
            background: #34495e;
            color: wheat;
            display: flex;
            align-items: center;
            padding-left: 10px;
            cursor: pointer;
        }
        .slide dt:first-of-type{
            border-top-left-radius: 10px;
            border-top-right-radius: 10px;
        }
        .slide dd{
            height: 100px;
            background: #f1c40f;
            overflow: hidden;
        }
        .slide dd div{
            padding: 10px;
        }
        .slide dd:last-of-type{
            border-bottom-left-radius: 10px;
            border-bottom-right-radius: 10px;
        }
    </style>
</head>
<body>
    <div class="slide s1">
        <dt>后盾人</dt>
        <dd>
            <div>houdunren.com</div>
        </dd>
        <dt>后盾人</dt>
        <dd>
            <div>hdcms.com</div>
        </dd>
        <dt>后盾人</dt>
        <dd>
            <div>hscmssss.com</div>
        </dd>
    </div>
</body>
</html>

<script>

    //生命一个动画类，将所需要的功能都放在类中
    //生命一个面板数据，将所有面板所需要的事件在构造函数中初始化
    //牵扯到所有面板的隐藏显示   那么就专门声明一个面板类，对数据进行控制
    
    class Animation{
        constructor(el){
            this.el = el;
            this.timeout = 5;
            this.isShow = true;
            this.defaultHeight = this.height;
        }

        //设置元素隐藏
        hide(callback){
            this.isShow = false;
            let id = setInterval(() => {
                if(this.height <= 0){
                    clearInterval(id);
                    callback && callback();
                    return;
                }
                this.height = this.height - 1;
            },this.timeout);
        }

        show(callback){
            this.isShow = true;
            let id = setInterval(() => {
                if(this.height > this.defaultHeight){
                    clearInterval(id);
                    callback && callback();
                    return;
                }
                this.height = this.height + 1;
            },this.timeout);
        }

        //获取元素高度
        get height(){
            return window.getComputedStyle(this.el).height.slice(0,-2)*1;
        }

        //设置元素高度
        set height(height){
            this.el.style.height = height + 'px';
        }
    }


    //应用层面
    class Slide{
        constructor(el){
            //对数据的初始化  包括点击的项   还有面板的项
            this.el = document.querySelector(el);
            this.links = this.el.querySelectorAll('dt');
            this.panels = [...this.el.querySelectorAll('dd')].map(
                item => new Panel(item)
            );
            this.bind();
        }

        bind(){
            this.links.forEach((item,i) => {
                item.addEventListener("click",()=>{
                    this.action(i);
                });
            });
        }

        action(i){
            Panel.hideAll(Panel.filter(this.panels,i),()=>{
                this.panels[i].show();
            });
        }

    }

    class Panel extends Animation{
        static num = 0;
        static hideAll(items,callback){
            if(Panel.num > 0) return;
            items.forEach(item => {
                Panel.num++;
                item.hide(() => {
                    Panel.num -- ;
                });
            });
            callback && callback();
        }

        static filter(items,i){
            return items.filter((item,index) => index != i);
        }
    }

    let hd = new Slide(".s1");
</script>